﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LoRel;

namespace QuickRunnable.Quick
{
    public class JoinRow {
        private object m_LHS;
        private object m_RHS;
        public JoinRow( object lhs, object rhs ) { throw new NotImplementedException(); }
    }

    public class Table<T> : NotifyDict<T>, IChangeNotice<T> {

        // my schema
        private Schema m_Schema;

        // sub schema
        private Dictionary<Schema, Index> m_Indices;

        public Table( LoRel.Schema key_provider ) : base( key_provider ) { m_Schema = key_provider; }

        public Index RegisterIndex( Schema expression ){}

        // Register to notify on a specific value (join condition on non-primary key)
        public IndexItem NotifyOnKey(Schema expression, IndexKey value ){}

        public event ChangeNotifyHandler ChangePending;
        public event BatchChangeNotifyHandler BatchChangePending;

        public class Index : IChangeNotice<T> {
            private Dictionary<IndexKey, IndexItem> m_Items;

            public event Action IndexItemAdded;
            public event ChangeNotifyHandler ChangePending;
            public event BatchChangeNotifyHandler BatchChangePending;
        }

        public class IndexItem : IChangeNotice<T>{
            private IndexKey m_IndexKey;

            // items within a given key
            private NotifyDict< T > m_Items;

            public event ChangeNotifyHandler ChangePending;
            public event BatchChangeNotifyHandler BatchChangePending;
        }
    }

    public class Join {

        private Dictionary< IndexKey, JoinClauseMatch > m_Matches;

        public IChangeNotice<T> CreateJoin<T>( Schema join_condition,
                                               Table<T> lhs, 
                                               Table<T> rhs ){
            Table<T> table = new Table< T >( GetUnion() );

            // at this point we need to 'pause' underlying data
            Table<T>.Index lhs_index = lhs.RegisterIndex(join_condition);
            Table<T>.Index rhs_index = rhs.RegisterIndex(join_condition);
            
            lhs_index.IndexItemAdded += delegate { AddLHS( value, lhs_index); };
            rhs_index.IndexItemAdded += delegate { AddRHS( value, rhs_index); };
        }

        private void AddRHS( IndexKey value, IChangeNotice<object> lhs_index)
        {
            if (m_Matches.ContainsKey(value)) return;
            
        }

        private void AddLHS( IndexKey value, IChangeNotice<object> lhs_index)
        {
        }
    }

    // so instead of requiring a join clause 
    public class JoinClauseMatch {

        private Table<T>.IndexItem m_LHS_Index;
        private Table<T>.IndexItem m_RHS_Index;

        private List< JoinRow > m_JoinRows;

        public JoinClauseMatch(Table<T>.IndexItem lhs, Table<T>.IndexItem rhs  ) {
            m_LHS_Index.ChangePending += HandleLHS;
            m_RHS_Index.ChangePending += HandleRHS;
        }

        private void HandleAddLeft( object lhs ) {
            // check for "PendingRow"
            foreach( Object rhs in m_RHS_Index ) {
                JoinRow row = new JoinRow( lhs, rhs );
            }
        }

        public void HandleAddRight( object rhs ) {
            foreach ( T lhs in m_LHS_Objects ){
                JoinRow row = new JoinRow(lhs, rhs);
            }
        }

        private void HandleLHS( ChangeNotifyItem item ) {
            if( item.ChangeType == ChangeType.Add ) {
                HandleAddLeft( item.New );
            }
        }

        private void HandleRHS( ChangeNotifyItem item ) {
            if (item.ChangeType == ChangeType.Add)
            {
                HandleAddRight(item.New);
            }
        }

    }

}
